package main

import "fmt"

// -----抽象层-----
// 抽象的观察者
type Listener interface {
	OnTeacherComing() // 观察者得到通知后要触发具体动作
}

// 抽象的通知者
type Notifier interface {
	AddListener(listener Listener)
	RemoveListener(listener Listener)
	Notify()
}

// -----实现层-----
// 观察者具体的学生
type StuZhang3 struct {
	BadThing string
}

func (s *StuZhang3) DoBadThing() {
	fmt.Println("张3 正在", s.BadThing)
}

func (s *StuZhang3) OnTeacherComing() {
	fmt.Println("张3 停止", s.BadThing)
}

type StuZhao4 struct {
	BadThing string
}

func (s *StuZhao4) DoBadThing() {
	fmt.Println("赵4 正在", s.BadThing)
}

func (s *StuZhao4) OnTeacherComing() {
	fmt.Println("赵4 停止", s.BadThing)
}

type StuWang5 struct {
	BadThing string
}

func (s *StuWang5) DoBadThing() {
	fmt.Println("王5 正在", s.BadThing)
}

func (s *StuWang5) OnTeacherComing() {
	fmt.Println("王5 停止", s.BadThing)
}

// 班长（通知者）
type ClassMonitor struct {
	listenerList []Listener // 需要通知的全部观察者集合
}

func (m *ClassMonitor) AddListener(listener Listener) {
	m.listenerList = append(m.listenerList, listener)
}
func (m *ClassMonitor) RemoveListener(listener Listener) {
	for index, l := range m.listenerList {
		if l == listener {
			m.listenerList = append(m.listenerList[:index], m.listenerList[index+1:]...)
			break
		}
	}
}

func (m *ClassMonitor) Notify() {
	for _, l := range m.listenerList {
		l.OnTeacherComing()
	}
}

// -----业务逻辑层-----
func main() {
	s1 := &StuZhang3{
		BadThing: "抄作业",
	}
	s2 := &StuZhao4{
		BadThing: "玩游戏",
	}
	s3 := &StuWang5{
		BadThing: "听音乐",
	}

	moniter := &ClassMonitor{}
	moniter.AddListener(s1)
	moniter.AddListener(s2)
	moniter.AddListener(s3)

	fmt.Println("上课了，老师没来，学生们都在忙自己的事...")
	s1.DoBadThing()
	s2.DoBadThing()
	s3.DoBadThing()

	fmt.Println("这个时候老师来了，班长通知了同学们...")
	moniter.Notify()

}
